package com.zz.framework.core.utils

import android.text.TextUtils

import com.zz.framework.core.BaseApp
import com.zz.framework.core.ext.isPhone
import com.zz.framework.core.ext.showToast

import java.util.regex.Pattern

/**
 * 校验字符
 */
class VerifyChar {
    /**
     * 校验的值
     */
    private var value: String? = null

    /**
     * 是否验证通过
     */
    var isValidNoShowToast: Boolean = false
        private set

    /**
     * 本次校验不通过的错误信息
     */
    private var error: String? = null


    /**
     * 是否验证通过，提示错误信息     * @param context     * @return
     */
    val isValid: Boolean
        get() {
            if (null != error && !this.isValidNoShowToast) {
                error?.showToast()
            }
            return this.isValidNoShowToast
        }

    init {
        init()
    }

    fun init() {
        isValidNoShowToast = true
        error = null
    }

    /**
     * * @param value 要校验的字符
     */
    fun with(value: String?): VerifyChar {
        this.value = value
        return this
    }

    /**
     * @param value 要校验的字符     * @param isRemoveSpace 是否去掉空格
     */
    fun with(value: String?, isRemoveSpace: Boolean): VerifyChar {
        if (value != null && isRemoveSpace) {
            this.value = value.replace(" ", "")
        }
        return this
    }


    /**
     * 必填     * @param error 错误信息     * @return
     */
    fun required(error: String?): VerifyChar {
        if (!isValidNoShowToast) {
            return this
        }
        if (TextUtils.isEmpty(this.value)) {//是空字符
            setFailureInfo(error ?: "")
        }
        return this
    }

    fun isPhone(error: String?): VerifyChar {
        if (!isValidNoShowToast) {
            return this
        }
        if (TextUtils.isEmpty(this.value) || this.value?.isPhone() != true) {
            setFailureInfo(error)
        }
        return this
    }

    /**
     * 必填     * @param error 错误信息     * @return
     */
    fun required(errorReId: Int): VerifyChar {
        return required(BaseApp.context.resources.getString(errorReId))
    }

    /**
     * 最小长度校验     *
     *
     * @param min   最小长度（包含）
     * @param error 错误信息
     * @return
     */
    fun minLength(min: Int, error: String): VerifyChar {
        if (!isValidNoShowToast) {
            return this
        }
        if (this.value!!.length < min) {
            setFailureInfo(error)
        }
        return this
    }

    /**
     * 最小长度校验     *
     *
     * @param min       最小长度（包含）
     * @param errorReId 错误信息
     * @return
     */
    fun minLength(min: Int, errorReId: Int): VerifyChar {
        return minLength(min, BaseApp.context.getResources().getString(errorReId))
    }

    /**
     * * 最大长度校验
     * * @param max 最大长度（包含）
     * * @param error 错误信息
     * * @return
     */
    fun maxLength(max: Int, error: String): VerifyChar {
        if (!isValidNoShowToast) {
            return this
        }
        if (this.value!!.length > max) {
            setFailureInfo(error)
        }
        return this
    }

    /**
     * * 最大长度校验
     * * @param max 最大长度（包含）
     * * @param error 错误信息
     * * @return
     */
    fun maxLength(max: Int, errorReId: Int): VerifyChar {
        return maxLength(max, BaseApp.context.getResources().getString(errorReId))
    }


    /**
     * 在 ... 之中     * @param min  最小长度（包含）
     * * @param max 最大长度（包含）     * @param error 错误信息
     * * @return
     */
    fun betweenLength(min: Int, max: Int, error: String): VerifyChar {
        if (!isValidNoShowToast) {
            return this
        }
        if (this.value!!.length > max || this.value!!.length < min) {
            setFailureInfo(error)
        }
        return this
    }


    /**
     * 在 ... 之中     * @param min  最小长度（包含）
     * * @param max 最大长度（包含）     * @param error 错误信息
     * * @return
     */
    fun betweenLength(min: Int, max: Int, errorReId: Int): VerifyChar {
        return betweenLength(
            min,
            max,
            BaseApp.context.getResources().getString(errorReId)
        )
    }


    /**
     * 比较this.value是否等于arg0
     * * @param arg0 要比较的值
     * * @param error 错误信息
     * * @return
     */
    fun equal(arg0: String, error: String): VerifyChar {
        if (!isValidNoShowToast) {
            return this
        }
        if (this.value != arg0) {
            setFailureInfo(error)
        }
        return this
    }

    /**
     * 比较this.value是否等于arg0
     * * @param arg0 要比较的值
     * * @param error 错误信息
     * * @return
     */
    fun equal(arg0: String, errorReId: Int): VerifyChar {
        return equal(arg0, BaseApp.context.getResources().getString(errorReId))
    }


    /**
     * 正则校验     * @param regularExpression 正则表达式
     * * @param error 错误信息     * @return
     */
    fun matches(regularExpression: String, error: String): VerifyChar {
        if (!isValidNoShowToast) {
            return this
        }
        if (!Pattern.matches(regularExpression, this.value!!)) {
            setFailureInfo(error)
        }
        return this
    }
    /**
     * 判断密码强度
     * 最少八个字符，至少一个大写字母，一个小写字母和一个数字
     */
    fun isPassword(error: String): VerifyChar {
        if (!isValidNoShowToast) {
            return this
        }
        val patternStr = "^(?!([a-zA-Z]+|\\d+)\$)[a-zA-Z\\d]{6,20}\$"
        val pattern = Pattern.compile(patternStr)
        val matcher = pattern.matcher(this.value);
        if (matcher.matches().not()) {
            setFailureInfo(error)
        }
        return this
    }

    /**
     * 正则校验     * @param regularExpression 正则表达式
     * * @param error 错误信息     * @return
     */
    fun matches(regularExpression: String, errorReId: Int): VerifyChar {
        return matches(
            regularExpression,
            BaseApp.context.getResources().getString(errorReId)
        )
    }


    /**
     * 设置校验失败信息     * @param error
     */
    internal fun setFailureInfo(error: String?) {
        this.error = error
        this.isValidNoShowToast = false
    }
}
